2

eventSource简单介绍

eventSource是用来解决web上服务器端向客户端推送消息的问题的。不同于ajax轮询的复杂和websocket的资源占用过大,eventSource(sse)是一个轻量级的,易使用的消息推送api

如何使用

客户端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript">
        (function() {
            var source = new EventSource('/stream')
            source.onopen = function(event) {
                console.log(event)
            }

            source.onmessage = function(event) {
                console.log(event)
            }

            source.onerror = function(error) {
                console.log(error)
            }
        })()
    </script>
</body>
</html>

代码很简单,实例化api,监听事件

服务端nodejs代码

服务端这几种实现使用其一就可以了

var http = require("http")
var fs = require('fs')

http.createServer(function (req, res) {

    var fileName = "." + req.url;

    if (fileName === "./stream") {
        res.writeHead(200, {
            "Content-Type":"text/event-stream", 
            "Cache-Control":"no-cache", 
            "Connection":"keep-alive"
        });

        res.write("retry: 10000\n");
        res.write("event: connecttime\n");
        res.write("data: " + (new Date()) + "\n\n");
        res.write("data: " + (new Date()) + "\n\n");

        interval = setInterval(function() {
            res.write("data: " + (new Date()) + "\n\n");
        }, 1000);

        req.connection.addListener("close", function () {
            clearInterval(interval);
        }, false);
  } else {
      fs.readFile('./index.html', 'utf8',function(err, html) {
          if (err) {
              console.log(err)
              return
          }
          res.end(html)
      })

  }
}).listen(9999);

服务端expressjs代码

var express = require('express')
var fs = require('fs')
var app = express()

app.get('/stream', function(req, res) {
    console.log(111)

    res.writeHead(200, {
        "Content-Type":"text/event-stream", 
        "Cache-Control":"no-cache", 
        "Connection":"keep-alive"
    });

    res.write("retry: 10000\n");
    res.write("event: connecttime\n");
    res.write("data: " + (new Date()) + "\n\n");
    res.write("data: " + (new Date()) + "\n\n");

    interval = setInterval(function() {
        res.write("data: " + (new Date()) + "\n\n");
    }, 1000);

    req.connection.addListener("close", function () {
        clearInterval(interval);
    }, false);
})

app.use(function(req, res) {
    fs.readFile('./index.html', 'utf8',function(err, html) {
        if (err) {
            console.log(err)
            return
        }
        res.send(html)
    })
})

app.listen(9999, function(err) {
    if (err) {
        console.log(err)
        return
    }
    console.log('listening on port 9999')
})

服务端koajs 1.x 代码

var koa = require('koa')
var fs = require('fs')
var PassThrough = require('stream').PassThrough

var app = koa()

app.use(function *() {
    var url = this.req.url
    if (url === '/stream') {
        var stream = new PassThrough()

        setInterval(function() {
            stream.write("data: " + (new Date()) + "\n\n")
        }, 1000);

        this.type = 'text/event-stream'
        this.body = stream
    } else {
        var html = yield koaFs
        this.body = html
    }
})

app.listen(9999, function(err) {
    if (err) {
        console.log(err)
        return 
    }
    console.log('listening on port 9999')
})

function koaFs(fn) {
    fs.readFile('./index.html', 'utf8', function(err, html) {
        fn(err, html)
    })
}

使用起来没什么问题,都可以正常运行,不过在多个客户端访问的时候,一个客户端连上之后,其他客户端就没有推送了,不知道为甚么?


frontoldman
4.5k 声望1.3k 粉丝

前端开发者